{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7184ec4c",
   "metadata": {},
   "source": [
    "**问题：**\n",
    "假设你正在为一个电影推荐系统设计一个简单的KNN算法。我们有以下一些用户的电影评分数据，数据由两个特征组成：用户对电影A和电影B的评分，分别在1-5之间。用户的标签（电影类型偏好）是动作片（标签0）或者是喜剧片（标签1）。我们有一个新用户，他给电影A评分为3，电影B评分为4。请问这个用户可能偏好哪种类型的电影？\n",
    "\n",
    "**数据：**\n",
    "\n",
    "| 用户   | 电影A评分 | 电影B评分 | 偏好类型 |\n",
    "| ------ | --------- | --------- | -------- |\n",
    "| 用户1  | 5         | 1         | 动作片   |\n",
    "| 用户2  | 4         | 2         | 动作片   |\n",
    "| 用户3  | 2         | 5         | 喜剧片   |\n",
    "| 用户4  | 1         | 4         | 喜剧片   |\n",
    "| 用户5  | 3         | 2         | 动作片   |\n",
    "| 用户6  | 2         | 5         | 喜剧片   |\n",
    "\n",
    "你需要做以下步骤：\n",
    "1. 构造数据\n",
    "2. 创建KNN模型\n",
    "3. 使用数据训练模型\n",
    "4. 预测新用户的喜好"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "580344b9",
   "metadata": {},
   "source": [
    "# 0. 引入核心包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "eab893d7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.neighbors import KNeighborsClassifier"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9014fc4",
   "metadata": {},
   "source": [
    "# 1. X, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "ad472357",
   "metadata": {},
   "outputs": [],
   "source": [
    "X = np.array([\n",
    "    [3,2],\n",
    "    [5,1],\n",
    "    [4,2],\n",
    "    [1,4],\n",
    "    [2,5],\n",
    "])\n",
    "\n",
    "y = np.array([0,0,0,1,1])  # 0表示动作片，1表示喜剧片"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c045b91f",
   "metadata": {},
   "source": [
    "# 2. 创建 KNN 模型\n",
    "k = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "5a970830",
   "metadata": {},
   "outputs": [],
   "source": [
    "knn = KNeighborsClassifier(n_neighbors=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5c7e735",
   "metadata": {},
   "source": [
    "# 3. 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "305adff6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-4 {color: black;}#sk-container-id-4 pre{padding: 0;}#sk-container-id-4 div.sk-toggleable {background-color: white;}#sk-container-id-4 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-4 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-4 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-4 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-4 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-4 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-4 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-4 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-4 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-4 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-4 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-4 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-4 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-4 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-4 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-4 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-4 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-4 div.sk-item {position: relative;z-index: 1;}#sk-container-id-4 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-4 div.sk-item::before, #sk-container-id-4 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-4 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-4 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-4 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-4 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-4 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-4 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-4 div.sk-label-container {text-align: center;}#sk-container-id-4 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-4 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-4\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KNeighborsClassifier(n_neighbors=1)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-4\" type=\"checkbox\" checked><label for=\"sk-estimator-id-4\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">KNeighborsClassifier</label><div class=\"sk-toggleable__content\"><pre>KNeighborsClassifier(n_neighbors=1)</pre></div></div></div></div></div>"
      ],
      "text/plain": [
       "KNeighborsClassifier(n_neighbors=1)"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn.fit(X,y)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "951b70d4",
   "metadata": {},
   "source": [
    "# 4. 用模型推理(预测)用户的喜好"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "ecdb1a68",
   "metadata": {},
   "outputs": [],
   "source": [
    "new_user = np.array([[3, 4]])\n",
    "prediction = knn.predict(new_user)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43106e0c",
   "metadata": {},
   "source": [
    "# 5. 数据可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "c29c87c1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkUAAAHJCAYAAACL5E3/AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABg0ElEQVR4nO3deVyU5f7/8dewo4BriAsuqYm5gitaR81wo5QW84uWmlqn0tLcSvO4ZlZWZqeOWalUR7Ks9JRphhbumWvHpWNqKmqoaQoiiiPcvz/4MTmyDswwzPh+Ph7zyLnu677uz2eumfx4rybDMAxEREREbnIezg5AREREpCxQUSQiIiKCiiIRERERQEWRiIiICKCiSERERARQUSQiIiICqCgSERERAVQUiYiIiAAqikREREQAFUUiHD16FJPJhMlkKrDf4MGDMZlMTJ06tXQCs4OcmE0mE3//+9/z7ZeRkUHlypUtfRMTE0svyP8vJ1ZHbjsxMdGSY87Ly8uLkJAQ+vTpww8//OCwbV8vMzOTyZMnU79+fXx8fDCZTAwePLhUti0i+fNydgAiUjqWLl3KP//5T3x8fHIt++abbzh//rwTonKOatWq0aNHDwCuXLnC7t27+eqrr/j666955513ePLJJx26/blz5zJjxgxq1KjB/fffj5+fH3fccYdDtykihVNRJHITCA8PZ9euXaxcuZKYmJhcy//973/j6elJ06ZN+fnnn0s/QGDWrFk8//zz1K5d2+HbCgsLIy4uzvLeMAymT5/O1KlTGTNmDA888ADBwcEO2/7y5csB2LBhA7feeqvDtiMittHhM5GbQGxsLB4eHixevDjXsgsXLrBy5Uq6du1KSEiIE6LLVr16dcLCwihXrlypb9tkMvGPf/yD+vXrc/nyZb777juHbu/EiRMAKohEyhgVRSIllJaWxqxZs2jRogUVKlQgICCA+vXr07dvX1avXp2rf3p6OrNmzSI8PJyAgAACAgJo3749H374YZ7jm0wm6taty9WrV5k+fTphYWH4+vrmuccnP9WrV+euu+5ixYoVpKSkWC377LPPyMjI4OGHHy5wjOPHj/P3v/+dOnXq4OvrS3BwMPfffz/btm2z6rdz505MJhPt2rXLd6x//vOfmEwmRo8ebWkr6JwiWz+z4vDw8KBFixZAdq7w1zlIgwcP5tSpUwwbNoxatWrh5eXFm2++aVn3+PHjjBgxgvr16+Pn50flypW555572Lx5s9U2cnI8cuQIgNW5TUePHi12vkX5jhR3zMzMTF555RVuu+02fH19CQ0N5bnnniMjIyPP9S5dusQrr7xC69atCQoKonz58oSFhTF8+HB+/fXXXP23bt1K3759qV69Oj4+PtSqVYthw4aRlJSU5/gijqTDZyIlkJmZyd13383WrVupWrUqnTt3xs/PjxMnTrBy5UrKly9P9+7dLf3PnDlDVFQU//3vfwkJCaFTp04YhsHmzZsZPHgw27dv55///Geu7WRlZRETE8P69evp1KkTzZs3p0qVKjbFOmDAANasWcMXX3zBkCFDLO2LFy+mXLly3HfffXnuSQLYs2cPd911F2fPnqVRo0bcf//9JCUlsWzZMr7++mvi4+Pp27cvABEREYSFhfHTTz9x+PBh6tevn2u8nO0UVohB8T+z4rh48SIAvr6+Vu1//PEHbdq04dq1a9xxxx1cuXLFskdry5YtREdHc/78eRo1akR0dDR//PEHq1ev5ttvv2Xx4sX069cPwHLe0Oeff86lS5cYNGiQZRsBAQElyreg70hJPsP+/fuzcuVKOnfuTKNGjdiwYQOvvvoqJ0+e5N///rdV3+TkZKKioti3bx+VKlWic+fO+Pr68ttvv/Huu+/SsGFDbrvtNkv/f/3rXzz99NMAtGnThjvvvJMDBw6wYMECvvrqK9atW0fjxo2LOHsidmCI3OSOHDliAEZhP4dBgwYZgDFlyhRL2/fff28ARps2bYzLly9b9U9JSTG2b99u1darVy8DMEaOHGlcuXLF0n7q1CmjdevWBmCsWrXKap2c2Bo0aGCcOHHCptxyYv7444+N1NRUw9/f3+jSpYtl+bFjxwyTyWTExsYahmEY3bt3NwDjhx9+sPTJysoymjVrZgDG+PHjjaysLMuyzz//3PDw8DACAgKM33//3dI+Y8YMAzCmT5+eK6ZDhw4ZgBEWFpZnrNdv2zCK95nl54cffjAAo1OnTrmWnT592ggKCjIAIyEhwao/YNx33315znH16tUNT09P49///rfVsm3bthmVKlUyAgICjDNnzlgtq1OnTr7fN0d8R0oyZuPGjY3k5GRL+2+//WZUrFjRAIxDhw5ZrdO1a1cDMB566CHj4sWLVsuOHDli/Pzzz5b3W7ZsMTw9PY2aNWvm+p188MEHBmC0a9cuz89IxFFUFMlNryRF0aeffmoAxqhRowrdzq5duywFVGZmZq7lO3fuNACjd+/eVu05sS1durRoCeUR88cff2wYhmE89NBDhoeHh+UvzpdeeskAjG+++cYwjLyLopzCr3bt2sbVq1dzbeP+++83AOPFF1+0tP322295Fj6GYRjTpk0zAGPGjBl5xnr9tov7meUnr6Lo8uXLxo8//mi0a9fOAIxGjRoZ165ds+rv6+ubZ7ExZ84cAzDGjBmT5/beeOMNAzDeeOMNq/b8iiJHfEdKOmZOgXi9ESNGGICxaNEiS9vWrVsNwAgODjZSU1NzrXOjPn36GIDx9ddf57m8d+/eBmDs3Lmz0LFE7EXnFImUQMuWLfHw8GDRokW8//77nDt3Lt++OSfvxsTE4OGR+6eXc67HTz/9lGuZyWTi3nvvLXG8Dz/8MFlZWcTHxwPZh7GCg4Pp1q1bvuts2LABgIceeghvb+9cyx955BGrfgD16tWjQ4cO/O9//2Pnzp1W/XMOnQ0YMKDQeEvymRVk3bp1lnN5/P39ad++PVu3bqVBgwYsX74cT09Pq/4RERHUrFkz3/juv//+PLdz5513AhQ5Pkd8R0oypre3N126dMnVnnMILDk52dK2Zs0aIPuk/sDAwDzzy5GVlcXatWspV66c1eHl69n62YnYg4oiuekVdtPGHIZh5Op/22238eqrr5Kens7jjz9OcHAwLVq0YPTo0fz3v/+1Wj/nRNoXXngh1w0Ec15paWmcPXs217aDg4NznedSHD169KBKlSosXryYXbt2sW/fPvr164eXV/6nF/7+++8A1K1bN8/lOe0nT560as8peq4/T2n79u38+uuvdOjQgXr16hUab0k+s4JUq1aNQYMGMWjQIIYOHcr48eP58ssv2b9/P2FhYbn653ebgJz4OnbsmGdsbdq0AShyfI74jpRkzJCQkFwFImApeq4/2Trn5PS8ziG70dmzZ0lLSyM9Pd1y88obX+PGjbP0FSktOtFabnrXXwKenp6e7yXh6enpAJQvX96qfcyYMTz00EMsX76chIQENmzYwJw5c3jzzTeZM2cOI0eOBLL/dQzZJ9sW5S+O6/n5+dnUPz/e3t489NBDzJs3j4kTJwJFO9m5IPkVlf369WPUqFEsWbKE2bNnW90SoCh7iaBkn1lBbrxPUWHy+/xz4nvwwQdzfS9u3F5ROOI7UpIx89qzZA85MQUEBPDAAw8U2LdJkyYOiUEkLyqK5KZXuXJl/P39uXz5Mr/99htNmzbNs99vv/0GQK1atXItCw0N5emnn+bpp5/m2rVrLFmyhEcffZTx48czcOBAKlWqZFkvJiaGMWPGOC6hQjz88MPMmzePb7/9lttuu422bdsW2L9GjRoAHDt2LM/lOXsibjy8VKVKFbp3786KFStITEykU6dOLFmyBG9vb8vVWIUpK59ZfmrVqsWBAwd4/vnnadWqlV3GA/vmW1qfYWhoKACHDx8utG/VqlXx8/OzHHou6t5aEUfT4TO56Xl6etKxY0cg+3EXeTl+/Di7d+/Gw8PD0jc/Xl5ePPzww7Rp04arV69y8OBBAKKiogBYtmyZHaO3XYcOHWjRogVVqlSxujQ/PznndixdupTMzMxcy3Muy87pd72cPULx8fF8//33nDp1iu7duxf5dgJl5TPLj73jc0S+pfUZ3n333QB88sknpKWlFdjXy8uLzp07k5qaytq1ax0al4gtVBSJgOUQ18svv8zWrVutlqWkpDBkyBCysrK4//77Lf8iBvjhhx9Ys2aN5XBAjiNHjvDLL79gMpks/1Jv164dUVFRbNq0ieHDh5Oamporjp9//plvv/3W3unlsnv3bs6ePctzzz1XaN/OnTvTrFkzjh49yuTJky3nVkH2X7RffvklAQEBeRZYffr0ITAwkC+++IKFCxcCRT90BmXrM8vL3//+d4KDg3n11Vd57733cn0Prl27xurVq9m7d2+RxnNEvqX1GbZt25YuXbpw5swZHn/8cS5dumS1/OjRo+zZs8fy/oUXXsDDw4NHH300zxt2pqWlsXDhQi5fvlyiuERs4uzL30TKivHjxxuA4eHhYURGRhr9+/c3oqOjjQoVKhiA0bRp01z3m8m5JPuWW24xevToYQwYMMDo1q2b4evrawDG008/bdX/9OnTRnh4uAEYFStWNDp37mzZTmhoqOVeMtcDjDp16hQrpxsvyS9MXpfkG4Zh/Pe//zWqVKliuW9NbGys0bFjRwMwvLy8jE8//TTfMQcOHGi5vDswMNBIT08vMNYbt12czyw/Bd2nqKD+gwYNyrfPli1bjKpVqxqAERoaavTs2dPo37+/cdddd1nu57Ns2TKrdQq6T5EjviP2HnPRokW5bk9hGIZx4sQJo1GjRgZgVK5c2ejdu7fRt29fIyIiwvDw8DDmzJlj1X/evHmGp6en5fd1//33G/369TPatWtn+Q2dP38+37xE7E1Fkch1Vq1aZfTp08cICQkxvLy8jKCgIKNt27bGK6+8YqSlpeXqf/DgQWPSpElGx44djerVqxs+Pj5GzZo1ja5duxpffPGF1Y0Oc1y+fNl46623jA4dOhgVKlQwfHx8jNDQUKNTp07G7NmzjePHj1v1LwtFkWFk3+jxscceM0JDQw1vb2+jatWqRkxMjLF169YCx1y9erWlKBo4cGChsea1bVs/s/w4oigyDMNITk42xo8fbzRp0sQoV66cUa5cOaN+/fpGnz59jLi4uFw3MiyoKDIMx3xH7DlmfkWRYRhGamqqMX36dKN58+aGv7+/ERAQYISFhRkjRowwDh48mKv/rl27jEGDBhl16tQxfHx8jIoVKxpNmjQxhgwZYqxYsSLP35CIo5gM47p94SIiIiI3KZ1TJCIiIoKKIhERERFARZGIiIgIoKJIREREBFBRJCIiIgKoKBLJ17lz5wgODrY8xqK0XL16lbp167J9+/ZS3a6IyM3uprskPysri99//53AwEA9b0cKNHHiRC5evMg///lPAPbs2cOcOXP48ccfOXfuHLVr12bIkCE8+eSTNo07a9YsXn75Zau2hg0bWhVB7733Hl9//TVff/11yRMREXEDhmFw8eJFatSo4bCHFd90RdGJEyesHtMgIiIiruP48eN5PpjbHrwcMmoZFhgYCGR/qEFBQXYd22w2891339GtWze8vb3tOnZZ4O75wV85XrlyhfHjxxf6xO8xY8Zw4MABVqxYUeRtzJo1i2+++YaNGzcW2O+ee+6hffv2TJo0qchjF8bd59Dd8wP3z1H5uT5H5ZiamkpoaKjl73FHuOmKopxDZkFBQQ4pisqVK0dQUJBbftndPT/4K8fNmzfTunXrQr8jly9fJjg42Kbvkq+vL4cPHyYsLAw/Pz8iIyOZNWsWtWvXturXoUMHfvzxR7t+T919Dt09P3D/HJWf63N0jo489eWmK4pEiuLYsWPUqFGjwD6bN2/m008/5ZtvvrFp7Hbt2hEXF0ejRo1ITk5m2rRp3Hnnnezdu9fqX0A1atTg2LFjxYpfRERsp6JIJA9XrlzBz88v3+V79+6lT58+TJkyhW7dutk0ds+ePS1/bt68Oe3ataNOnTp89tlnDB061LLM39+f9PR024MXEZFi0SX5InmoUqUK58+fz3PZ/v376dq1K48//rhdzvepWLEit912G4cOHbJq//PPP7nllltKPL6IiBSNiiKRPLRs2ZL9+/fnat+3bx9dunRh0KBBzJw50y7bSktL4/Dhw1SvXt2qfe/evYSHh9tlGyIiUjgVRSJ5iIqKYt++fVZ7i/bu3UuXLl3o1q0bo0eP5tSpU5w6dYo//vjDprHHjh3LunXrOHr0KJs3b+a+++7D09OT2NhYq34bNmyw+dCciIgUn4oikTw0a9aMiIgIPvvsM0vb559/zh9//MG///1vqlevbnm1adPG0ufo0aOYTCYSExPzHfvEiRPExsbSqFEjHnroIapUqcKPP/5odahsy5YtpKSk8OCDDzokPxERyU1FkUg+Jk+ezNy5c8nKygJg6tSpGIaR63X9Y0COHDlCxYoVadGiRb7jLlmyhN9//52MjAxOnDjBkiVLqF+/vlWfN998k3HjxuHv7++Q3EREJDddfSaSj+joaA4ePMjJkyeLfBf0lStXMnHiRCpVqlTs7V69epVmzZrx7LPPFnsMERGxnYoikQKMGjXKpv6zZ88u8TZ9fHzsehdrEREpGh0+k5uekZWOcelDsv7oSdaZO7PbLi3AyEpxcmQiIlKanFoUTZ06FZPJZPUKCwsrcJ2lS5daHo/QrFkzVq5cWUrRijsyslIw/uyHcfElyPwNjEvZ7WnzMM72wchMdnKEIiJSWpy+p6hJkyYkJydbXgU9JHPz5s3ExsYydOhQdu3aRUxMDDExMezdu7cUIxZ3YqROh2uHAOP/v3JkQdZpjAvjnBSZiIiUNqcXRV5eXoSEhFheVatWzbfv3Llz6dGjB+PGjaNx48bMmDGDiIgI3n777VKMWNyFkXkWrqwEMvPpkQnmnzDMB0szLBERcRKnn2h98OBBatSoUeDTwnNs2bKF0aNHW7V1796d5cuX5zt+RkYGGRkZlvepqalA9lN8zWZzyRO4Ts549h63rHC3/IyrezGueXH9zyBzXxYRc+Zw7S1PqOwLgOnybkzUdU6QduZuc3gjd88P3D9H5ef6HJVjaXxmJsMwjMK7OcaqVatIS0uzelr4yZMncz0tPIePjw8ffvih1Z1///WvfzFt2jROnz6d5zamTp3KtGnTcrXHx8dTrlw5+yUjri8ri86jR1Ph6FEuVavG9rFjudCwobOjEhERID09nf79+5OSkkJQUJBDtuHUouhGFy5coE6dOrzxxhtWTwvPUZyiKK89RaGhoZw9e9buH6rZbCYhIYGoqCi8vb3tOnZZ4G75GVmXMP64G/jr+5G18xpZj/1J+TNnMLxNZE4MIeu5HzF5Vc9/IBfibnN4I3fPD9w/R+Xn+hyVY2pqKlWrVnVoUeT0w2fXy+9p4TlCQkJyFT+nT58mJCQk3zF9fX3x9fXN1e7t7e2wL6Qjxy4L3Ce/imQF3Q/pH5JzkrU5wpfv33iDHoufwnNVKl7TkmHX07BoEVSu7Nxw7ch95jBv7p4fuH+Oys/12TvH0vi8nH6i9fXye1p4jsjISNauXWvVlpCQQGRkZGmEJ27IFDgWfLv8/3eeAFwLCODa/FCyXgnH8PGBr76C8HC47nEeIiLifpxaFBX2tPCBAwcyYcIES/+RI0fy7bff8vrrr/O///2PqVOnsn37dkaMGOGsFMTFmUw+mCr+C1OlBeAbBd5Ns9srvY5p3E+YtmyB+vWzX0V81IeIiLgmpx4+y3la+Llz57jlllu44447rJ4WnpSUhIfHX3Vbhw4diI+PZ9KkSUycOJGGDRuyfPlymjZt6qwUxA2YTB7geycm3zvxMJuBlZh878Jk8oKICNi5E65cAc/sPUlcuQJpaVDA7SNERMT1OLUoWrJkSYHLExMTc7X17duXvn37OigikTwEBWW/cowenX1I7ZNP4M47nReXiIjYVZk6p0ikzLt4Eb7/Hk6ehC5d4KWXICvL2VGJiIgdqCgSsUVgIGzfDg8/DJmZ8MIL0LMnnDnj7MhERKSEVBSJ2CogAD76CBYsAH9/+O47aNkS8jjcKyIirkNFkUhxmEwwZAhs2wa33w7JydC3b/YJ2CIi4pLK1M0bRVxOkybw00/w9NPQp0/2XiQREXFJKopESqp8eVi40Lpt9ersS/jvvts5MYmIiM10+EzE3k6ehAEDoFs3mDQJrl1zdkQiIlIEKopE7K1yZXjgATAMmDkTunbNLpRERKRMU1EkYm/+/jB/fvbNHQMCYP367KvTVq1ydmQiIlIAFUUijvJ//5f9iJDwcDh7Fnr1guee080eRUTKKBVFIo7UsCFs3gzDh2e///NP8NDPTkSkLNLVZyKO5ucHb7+dfefrLl3+ar92Dbz0ExQRKSv0T1aR0hIdDeXKZf85Kyv7/ZgxcPWqc+MSERFARZGIc6xdm/14kDfegDvvhCNHnB2RiMhNT0WRiDNERcHy5VCxYvYdscPD4csvnR2ViMhNTUWRiLP06QO7d0P79pCSkn1vo6efhowMZ0cmInJTUlEk4kx16mTfx2jcuOz3b78NAwc6NyYRkZuUiiIRZ/P2hldfhRUroGZNmDDB2RGJiNyUVBSJlBXR0XD4cPbdr3N8/z1cvuy0kEREbiYqikTKEl/fv/68fTv06JF9ztGBA86LSUTkJqGiSKSsSkvLvjrtv/+FVq1g8WJnRyQi4tZUFImUVZ07Z1+d1rkzXLoEDz8Mw4ZBerqTAxMRcU8qikTKsho1YM0amDIFTCZYsADatoX9+50dmYiI21FRJFLWeXrC1KnZxVFICOzbBytXOjsqERG3o6dRiriKu+7KPpw2bx6MHu3saERE3I72FIm4kmrVsvcaefz/n+6lS3DffbBnj1PDEhFxByqKRFzZP/6R/Qy1tm3h/ffBMJwdkYiIy1JRJOLKJkzIvpfRlSvw+OMwYABcvOjsqEREXJKKIhFXdsst8M038Mor2Sdkf/IJRETArl3OjkxExOWoKBJxdR4eMH589oNlQ0Ph0KHsu2D/5z/OjkxExKWoKBJxFx06ZO8huvdeqFAB2rRxdkQiIi6lzBRFL7/8MiaTiVGjRuXbJy4uDpPJZPXy8/MrvSBFyroqVbL3EG3dmn3jxxzHjzsvJhERF1EmiqJt27Yxf/58mjdvXmjfoKAgkpOTLa9jx46VQoQiLsRkgnr1/nr/+efQoAHMnaur00RECuD0oigtLY0BAwbw/vvvU6lSpUL7m0wmQkJCLK9q1aqVQpQiLmzlSrh6FUaNwrNvX7zT0pwdkYhImeT0O1oPHz6c6Oho7r77bl588cVC+6elpVGnTh2ysrKIiIjgpZdeokmTJvn2z8jIICMjw/I+NTUVALPZjNlsLnkC18kZz97jlhXunh+4aY7vvotH8+Z4PPccHl99RectW8isWRM6dnR2ZHbnlvN3A3fPUfm5PkflWBqfmckwnLc/fcmSJcycOZNt27bh5+dH586dadmyJW+++Wae/bds2cLBgwdp3rw5KSkpvPbaa6xfv559+/ZRq1atPNeZOnUq06ZNy9UeHx9PuXLl7JmOSJlW4dAh2syeTfnTp8ny9GT/I49wuHfvv+6OLSJShqWnp9O/f39SUlIICgpyyDacVhQdP36c1q1bk5CQYDmXqLCi6EZms5nGjRsTGxvLjBkz8uyT156i0NBQzp49a/cP1Ww2k5CQQFRUFN7e3nYduyxw9/zA/XM0nz3L+b59qblpEwDXfvgBw432GLn7/IH756j8XJ+jckxNTaVq1aoOLYqcdvhsx44dnDlzhoiICEtbZmYm69ev5+233yYjIwNPT88Cx/D29iY8PJxDhw7l28fX1xdfX98813XUF9KRY5cF7p4fuHGOVauyfexYQmJj8UxKwqtzZ2dH5BBuO3/XcfcclZ/rs3eOpfF5Oa0o6tq1K3tueIjlo48+SlhYGM8991yhBRFkF1F79uyhV69ejgpTxP2YTGQ9/jie1/8P5uRJWLIEnn1Wh9NE5KbltKIoMDCQpk2bWrWVL1+eKlWqWNoHDhxIzZo1mTVrFgDTp0+nffv2NGjQgAsXLjB79myOHTvGsGHDSj1+EbeRmQmxsbBhAyQkwEcfQXCws6MSESl1ZfqfhElJSSQnJ1venz9/nscee4zGjRvTq1cvUlNT2bx5M7fffrsToxRxcR4eMHgw+PvD6tXQsiWsW+fsqERESp3TL8m/XmJiYoHv58yZw5w5c0ovIJGbgckEQ4ZA27bw0EPwyy9w110wZQq88EL2g2ZFRG4CZXpPkYiUoqZNYdu27L1GWVnZRVG3bnD2rLMjExEpFSqKROQv5cvDokXw4YdQrhycPp39XxGRm0CZOnwmImXEwIHZh9Pgr6IoKyv75aX/bYiIe9KeIhHJW1hY9ivHK69A167Zl++LiLghFUUiUrgLF+DVV2H9+uyr07791tkRiYjYnYoiESlcxYqwdWt2QXT2LPTsCRMmgBs/1FJEbj4qikSkaG67DbZsgaeeyn7/8svQuTMcP+7UsERE7EVFkYgUnZ8fvPMOfPYZBAXB5s3Qvj1cvuzsyERESkxFkYjYrm9f2LULWreGiROz74YtIuLidG2tiBTPrbfCpk1w/YNl9+yBwECoW9dpYYmIFJf2FIlI8fn4ZD8mBCAlBWJiIDwcli1zalgiIsWhokhE7OPSJbjlluzL9++/H555BjIynB2ViEiRqSgSEfuoUQM2bICxY7Pf//Of0LEjHD7s3LhERIpIRZGI2I+3N8yeDStWQOXKsGMHRETA0qXOjkxEpFAqikTE/qKjYffu7D1FqanZD5k1DGdHJSJSIBVFIuIYoaGQmAgvvggffvjXCdkiImWUiiIHOXfuHMHBwRw9erTUt92+fXu++OKLUt+uSC5eXvDCC9knYOd45hmIj3f4pp31G7x69Sp169Zl+/btpbpdESk5FUUOMnPmTPr06UPd6+7X8swzz9CqVSt8fX1p2bJlibexZMkSTCYTMTExVu2TJk3i+eefJysrq8TbELGrlSuzT8AeMAAeewzS0x22qRt/g+fOnaNHjx7UqFEDX19fQkNDGTFiBKmpqcXexssvv4zJZGLUqFGWNh8fH8aOHctzzz1XwgxEpLSpKHKA9PR0FixYwNChQ3MtGzJkCP369SvxNo4ePcrYsWO58847cy3r2bMnFy9eZNWqVSXejohddesGkydnH0r74ANo1w5++cXum8nrN+jh4UGfPn346quv+PXXX4mLi2PNmjU88cQTxdrGtm3bmD9/Ps2bN8+1bMCAAWzcuJF9+/YVOwcRKX0qihxg1apV+Pr60r59e6v2t956i+HDh3PrrbeWaPzMzEwGDBjAtGnT8hzL09OTXr16sWTJkhJtR8TuvLxg2jRISIBq1WDv3uxHhXz4oV03k9dvsFKlSjz55JO0bt2aOnXq0LVrV5566ik2bNhg8/hpaWkMGDCA999/n0qVKuVaXqlSJTp27KjfoIiLUVHkAJs2baJVq1YOG3/69OkEBwfnuScqR9u2bYv1P3uRUtG1a/bVaV27Zh9CGzwYxoyx2/BF+Q3+/vvvfPnll3Tq1Mnm8YcPH050dDR33313vn30GxRxPSqKHODYsWPUqFHDIWNv3LiRBQsW8P777xfYr0aNGhw/flznFUnZFRICq1fDjBnZe5C6dbPb0AX9BmNjYylXrhw1a9YkKCiIDz74wKaxlyxZws6dO5k1a1aB/WrUqMGxY8dsGltEnEtFkQNcuXIFPz8/u4978eJFHnnkEd5//32qVq1aYF9/f3+ysrLI0GMWpCzz9IRJk+DQIeje/a/2Y8dKdF+jgn6Dc+bMYefOnfznP//h8OHDjB49usjjHj9+nJEjR7J48eJCf+P+/v6kO/BEchGxPy9nB+COqlSpwvnz5+0+7uHDhzl69Cj33nuvpS1nT5CXlxcHDhygfv36APz555+UL18ef39/u8chYnd16vz15yNHsh8qGx0N774LgYE2D1fQbzAkJISQkBDCwsKoXLkyd955J//4xz+oXr16oePu2LGDM2fOEBERYWnLzMxk/fr1vP3222RkZODp6Qlk/wZvuf5WBCJS5qkocoCWLVvyySef2H3csLAw9uzZY9U2adIkLl68yNy5cwkNDbW07927l/DwcLvHIOJwmzZBWlr2vYy2bYPPPgMbb2FR1N9gzj8qirpHtWvXrrl+g48++ihhYWE899xzloII9BsUcUUqihwgKiqKSZMmcf78easrUw4dOkRaWhqnTp3i8uXL7N69G4Dbb78dHx+fQsf18/OjadOmVm0VK1YEyNW+YcMGutnxHA2RUvPww1CvHvzf/8HBg9C+PcyZA088UeS7Yuf1G1y5ciWnT5+mTZs2BAQEsG/fPsaNG0fHjh2t7idWkMDAwFy/tfLly1OlSpU8f4MzZswo0rgiUjbonCIHaNasGREREXz22WdW7cOGDSM8PJz58+fz66+/Eh4eTnh4OL///rulj8lkIi4urkTbP3nyJJs3b+bRRx8t0TgiTtOxY/bVaffcAxkZ8NRT0K8fpKQUafW8foP+/v68//773HHHHTRu3Jhnn32W3r17s2LFCkufo0ePYjKZSExMLFH4W7ZsISUlhQcffLBE44hI6dKeIgeZPHky48aN47HHHsPDI7v2LOx/tEeOHMHLy4uOHTsWeTt5FVBvvfUWgwcPplatWraELFK2VKkCX30Fb7wBzz8PS5fC7bfD1KlFWv3G32CXLl3YvHlzgescOXKEihUr0qJFiyKHmdfv+s0332TcuHE6p0/ExagocpDo6GgOHjzIyZMnrc71KcjKlSt5/PHHadiwYYm2HRwcbNMVNSJllsmUff+iO+6AV1+FCROKvGpxf4MTJ07M84aMRXX16lWaNWvGs88+W+wxRMQ5VBQ50PXPQyqK4cOH22W7Y+x4EzyRMqFdO7j+IcfXrsHdd0OHDvDSS/muZvkNzpgBmZmF7mWaPXt2iUP18fFh0qRJJR5HREqfzikqIcMwMK58R9a5R8g68zcAslJfwrh22MmRibixGTNg3TqYNQsef7zwvpMnZ98TSUSkAGWmKMrradN5Wbp0KWFhYfj5+dGsWTNWrlxZOgHmwTAMjNR/YFwYAebtYKRlL7i8DONsb4yM9U6LTcSt9e4NOc/9e/996NEj75s95hRE06fDP/5RujGKiMspE0VRQU+bvt7mzZuJjY1l6NCh7Nq1i5iYGGJiYti7d28pRXqDK8vhcs7VLZnXLcgErmGcH4GRVbSrZUTEBq1awc6d0Ldv9vvVqyEsDM6d+6uPCiIRsZHTi6LCnjZ9vblz59KjRw/GjRtH48aNmTFjBhEREbz99tulFK0141Ic+X+EBpABl5eVXkAiN5MKFeDTT2HevOxnp/36K16NGlHx11/xmDlTBZGI2MzpJ1pf/7TpF198scC+W7ZsyXVVVffu3Vm+fHm+62RkZFjdrTY1NRUAs9mM2WwudtyGcQ3jym+At6XtWqav1X/BAy7/Fw+f4m+nLMn5vEryuZV17p6jW+Y3dCi0aoVXjx6Y/vyTOyZMwDMzk8wpU8h6/nlwp1xx0zm8jvJzfY7KsTQ+M6cWRTlPm962bVuR+p86dYpq1apZtVWrVo1Tp07lu86sWbOYNm1arvbvvvuOcuXK2RZwLnkXcWt23/gvU+ed9+QICQkJzg7B4dw9R3fMz+udd+gxYEB2QeTlxYrwcHDiOYeO5o5zeD3l5/rsnWNpPGDZaUVRztOmExISHPJE+RwTJkyw2ruUmppKaGgo3bp1IygoqERjZ53/O1zdAWQ/P+lapi9rdv+Du1vOwMsze++UKWgaJv97CxjFdZjNZhISEoiKisLb27vwFVyQu+fozvl5zJyJZ1YWmV5eeF67xj27dpH1wgvODsvu3HkOQfm5A0flmHOkx5GcVhTZ8rTpHCEhIZw+fdqq7fTp04SEhOS7HV9fX3x9fXO1e3t7l3iyjAqDMc5vzNXu5ZmBt9c18KiEKbAXJpN7ffHt8dmVde6eo9vlN2MGTJtG5pQprAgP555du/CcNi37/yFuek6R283hDZSf67N3jqXxeTntROucp03v3r3b8mrdujUDBgxg9+7duQoigMjISNauXWvVlpCQQGRkZGmFbcXk+zdMgc///3fXx2sCUxCmSgswmRy3F0xEsLrKLGfPUNYLL2SfZD15cvZyEZEicNqeoqI8bXrgwIHUrFmTWbNmATBy5Eg6derE66+/TnR0NEuWLGH79u289957pR5/DlP5IeBzJ8blT+Dy/7LbAsdiCozB5FGyw3MiUogbL7u//kTMnD1EkydbvxcRyYfTrz4rSFJSkuVhqgAdOnQgPj6eSZMmMXHiRBo2bMjy5ctzFVelzeTdEJP3ZDz8zcBKTOViMXm4925REacryn2IVBiJiA3KVFF049Om83r6dN++fembc8M2Ebl5ZWYW7T5EOcszMwvuJyI3vTJVFImIFFkhD3e1oj1EIlIETr+jtYiIiEhZoKJIREREBBVFIiIiIoCKIhERERFARZGIiIgIoKJIREREBFBRJCIiIgKoKBIREREBVBSJiIiIACqKRERERAAVRSIiIiKAiiIRERERQEWRiIiICKCiSERERARQUSQiIiICqCgSERERAVQUiYiIiAAqikREREQAFUUiIiIigIoiEREREUBFkYiIiAigokhEREQEUFEkIiIiAqgoEhEREQFUFImIiIgAKopEREREABVFIiIiIoCKIhEREREAvGxdYfTo0Xm2m0wm/Pz8aNCgAX369KFy5colDk5ERESktNhcFO3atYudO3eSmZlJo0aNAPj111/x9PQkLCyMf/3rX4wZM4aNGzdy++232z1gEREREUew+fBZnz59uPvuu/n999/ZsWMHO3bs4MSJE0RFRREbG8vJkyf529/+xrPPPlvoWPPmzaN58+YEBQURFBREZGQkq1atyrd/XFwcJpPJ6uXn52drCiIiIiK52LynaPbs2SQkJBAUFGRpq1ChAlOnTqVbt26MHDmSyZMn061bt0LHqlWrFi+//DINGzbEMAw+/PBD+vTpw65du2jSpEme6wQFBXHgwAHLe5PJZGsKIiIiIrnYXBSlpKRw5syZXIfG/vjjD1JTUwGoWLEiV69eLXSse++91+r9zJkzmTdvHj/++GO+RZHJZCIkJMTWsEVEREQKZHNR1KdPH4YMGcLrr79OmzZtANi2bRtjx44lJiYGgJ9++onbbrvNpnEzMzNZunQply5dIjIyMt9+aWlp1KlTh6ysLCIiInjppZfyLaAAMjIyyMjIsLzPKdzMZjNms9mmGAuTM569xy0r3D0/cP8clZ/rc/cclZ/rc1SOpfGZmQzDMGxZIS0tjWeffZaPPvqIa9euAeDl5cWgQYOYM2cO5cuXZ/fu3QC0bNmy0PH27NlDZGQkV65cISAggPj4eHr16pVn3y1btnDw4EGaN29OSkoKr732GuvXr2ffvn3UqlUrz3WmTp3KtGnTcrXHx8dTrly5oiUtIiIiTpWenk7//v1JSUmxOoXHnmwuinKkpaXx22+/AXDrrbcSEBBQrACuXr1KUlISKSkpfP7553zwwQesW7euSFeumc1mGjduTGxsLDNmzMizT157ikJDQzl79qzdP1Sz2UxCQgJRUVF4e3vbdeyywN3zA/fPUfm5PnfPUfm5PkflmJqaStWqVR1aFNl8+CxHQEAAzZs3L3EAPj4+NGjQAIBWrVqxbds25s6dy/z58wtd19vbm/DwcA4dOpRvH19fX3x9ffNc11FfSEeOXRa4e37g/jkqP9fn7jkqP9dn7xxL4/OyuSi6dOkSL7/8MmvXruXMmTNkZWVZLc/Ze1RcWVlZVnt2CpKZmcmePXvyPdwmIiIiUlQ2F0XDhg1j3bp1PPLII1SvXr1El8RPmDCBnj17Urt2bS5evEh8fDyJiYmsXr0agIEDB1KzZk1mzZoFwPTp02nfvj0NGjTgwoULzJ49m2PHjjFs2LBixyAiIiICxSiKVq1axTfffEPHjh1LvPEzZ84wcOBAkpOTqVChAs2bN2f16tVERUUBkJSUhIfHX/eXPH/+PI899hinTp2iUqVKtGrVis2bN+vO2SIiIlJiNhdFlSpVsttzzRYsWFDg8sTERKv3c+bMYc6cOXbZtoiIiMj1bH7Mx4wZM5g8eTLp6emOiEdERETEKWzeU/T6669z+PBhqlWrRt26dXOdDb5z5067BSciIiJSWmwuinLuWi0iIiLiTmwuiqZMmeKIOEREREScyuZzikRERETcUZH2FFWuXJlff/2VqlWrUqlSpQLvTfTnn3/aLTgRERGR0lKkomjOnDkEBgZa/lySGzaKiIiIlEVFKooGDRpk+fPgwYMdFYuIiIiI09h8TpGnpydnzpzJ1X7u3Dk8PT3tEpSIiIhIabO5KDIMI8/2jIwMfHx8ShyQiIiIiDMU+ZL8t956CwCTycQHH3xAQECAZVlmZibr168nLCzM/hGKiIiIlIIiF0U5zxwzDIN3333X6lCZj48PdevW5d1337V/hCIiIiKloMhF0ZEjRwDo0qULX375JZUqVXJYUCIiIiKlzeY7Wv/www+OiENERETEqWwuigBOnDjBV199RVJSElevXrVa9sYbb9glMBEREZHSZHNRtHbtWnr37s2tt97K//73P5o2bcrRo0cxDIOIiAhHxCgiIiLicDZfkj9hwgTGjh3Lnj178PPz44svvuD48eN06tSJvn37OiJGEREREYezuSj65ZdfGDhwIABeXl5cvnyZgIAApk+fziuvvGL3AEVERERKg81FUfny5S3nEVWvXp3Dhw9blp09e9Z+kYmIiIiUIpvPKWrfvj0bN26kcePG9OrVizFjxrBnzx6+/PJL2rdv74gYRURERBzO5qLojTfeIC0tDYBp06aRlpbGp59+SsOGDXXlmYiIiLgsm4qizMxMTpw4QfPmzYHsQ2m6i7WIiIi4A5vOKfL09KRbt26cP3/eUfGIiIiIOIXNJ1o3bdqU3377zRGxiIiIiDiNzUXRiy++yNixY1mxYgXJycmkpqZavURERERckc0nWvfq1QuA3r17YzKZLO2GYWAymcjMzLRfdCIiIiKlRA+EFREREaEYRVGnTp0cEYeIiIiIU9l8TpGIiIiIO1JRJCIiIoKKIhERERHAyUXRvHnzaN68OUFBQQQFBREZGcmqVasKXGfp0qWEhYXh5+dHs2bNWLlyZSlFKyIiIu6sxEXR1atXLc9Cs1WtWrV4+eWX2bFjB9u3b+euu+6iT58+7Nu3L8/+mzdvJjY2lqFDh7Jr1y5iYmKIiYlh7969JUlBRERExLaiaNGiRTz99NMsXrwYgAkTJhAYGEiFChWIiori3LlzNm383nvvpVevXjRs2JDbbruNmTNnEhAQwI8//phn/7lz59KjRw/GjRtH48aNmTFjBhEREbz99ts2bVdERETkRkW+JH/mzJnMnDmTjh07Eh8fz8aNG1m+fDnTp0/Hw8ODt956i0mTJjFv3rxiBZKZmcnSpUu5dOkSkZGRefbZsmULo0ePtmrr3r07y5cvz3fcjIwMMjIyLO9z7rptNpsxm83FijU/OePZe9yywt3zA/fPUfm5PnfPUfm5PkflWBqfmckwDKMoHRs2bMj06dOJjY1l+/bttGvXjs8++4wHHngAgFWrVvHEE09w7NgxmwLYs2cPkZGRXLlyhYCAAOLj4y13zb6Rj48PH374IbGxsZa2f/3rX0ybNo3Tp0/nuc7UqVOZNm1arvb4+HjKlStnU6wiIiLiHOnp6fTv35+UlBSCgoIcso0i7ylKSkrijjvuAKB169Z4eXnRtGlTy/LmzZuTnJxscwCNGjVi9+7dpKSk8PnnnzNo0CDWrVvH7bffbvNYeZkwYYLV3qXU1FRCQ0Pp1q2b3T9Us9lMQkICUVFReHt723XsssDd8wP3z1H5uT53z1H5uT5H5Vgaz1ctclFkNpvx9fW1vPfx8bFK1svLq1jPPfPx8aFBgwYAtGrVim3btjF37lzmz5+fq29ISEiuPUKnT58mJCQk3/F9fX2t4s7h7e3tsC+kI8cuC9w9P3D/HJWf63P3HJWf67N3jqXxedn0mI/9+/dz6tQpIPsBsP/73/8sV56dPXvWLgFlZWVZnQN0vcjISNauXcuoUaMsbQkJCfmegyQiIiJSVDYVRV27duX6U5DuueceAEwmE4ZhYDKZbNr4hAkT6NmzJ7Vr1+bixYvEx8eTmJjI6tWrARg4cCA1a9Zk1qxZAIwcOZJOnTrx+uuvEx0dzZIlS9i+fTvvvfeeTdsVERERuVGRi6IjR47YfeNnzpxh4MCBJCcnU6FCBZo3b87q1auJiooCss9j8vD4664BHTp0ID4+nkmTJjFx4kQaNmzI8uXLrc5tEhERESmOIhdFderUsfvGFyxYUODyxMTEXG19+/alb9++do9FREREbm569pmIiIgIKopEREREABVFIiIiIoCKIhERERGgmEXRtWvXWLNmDfPnz+fixYsA/P7775Z7FomIiIi4GpvuUwRw7NgxevToQVJSEhkZGURFRREYGMgrr7xCRkYG7777riPiFBEREXEom/cUjRw5ktatW3P+/Hn8/f0t7ffddx9r1661a3AiIiIipcXmPUUbNmxg8+bN+Pj4WLXXrVuXkydP2i0wERERkdJk856irKysPB/8euLECQIDA+0SlIiIiEhps7ko6tatG2+++ablvclkIi0tjSlTptCrVy97xiYiIiJSamw+fPb666/TvXt3br/9dq5cuUL//v05ePAgVatW5ZNPPnFEjCIiIiIOZ3NRVKtWLX7++WeWLFnCf//7X9LS0hg6dCgDBgywOvFaRERExJXYXBQBeHl58fDDD9s7FhERERGnKVJR9NVXX9GzZ0+8vb356quvCuzbu3dvuwQmIiIiUpqKVBTFxMRw6tQpgoODiYmJybefyWTK88o0ERERkbKuSEVRVlZWnn8WERERcRc2X5J//PhxR8QhIiIi4lQ2F0V169alU6dOvP/++5w/f94RMYmIiIiUOpuLou3bt9O2bVumT59O9erViYmJ4fPPPycjI8MR8YmIiIiUCpuLovDwcGbPnk1SUhKrVq3illtu4fHHH6datWoMGTLEETGKiIiIOJzNRVEOk8lEly5deP/991mzZg316tXjww8/tGdsIiIiIqWm2EXRiRMnePXVV2nZsiVt27YlICCAd955x56xiYiIiJQam+9oPX/+fOLj49m0aRNhYWEMGDCA//znP9SpU8cR8YmIiIiUCpuLohdffJHY2FjeeustWrRo4YiYREREREqdzUVRUlISJpPJEbGIiIiIOI3NRZHJZOLChQssWLCAX375BYDbb7+doUOHUqFCBbsHKCIiIlIainWfovr16zNnzhz+/PNP/vzzT+bMmUP9+vXZuXOnI2IUERERcTib9xQ9++yz9O7dm/fffx8vr+zVr127xrBhwxg1ahTr16+3e5AiIiIijmZzUbR9+3arggjAy8uL8ePH07p1a7sGJyIiIlJabD58FhQURFJSUq7248ePExgYaJegREREREqbzUVRv379GDp0KJ9++inHjx/n+PHjLFmyhGHDhhEbG+uIGEVEREQczuai6LXXXuP+++9n4MCB1K1bl7p16zJ48GAefPBBXnnlFZvGmjVrFm3atCEwMJDg4GBiYmI4cOBAgevExcVhMpmsXn5+framISIiImLF5nOKfHx8mDt3LrNmzeLw4cMA1K9fn3Llytm88XXr1jF8+HDatGnDtWvXmDhxIt26dWP//v2UL18+3/WCgoKsiifdN0lERERKyuaiKEe5cuVo1qxZiTb+7bffWr2Pi4sjODiYHTt28Le//S3f9UwmEyEhISXatoiIiMj1ilwUDRkypEj9Fi5cWOxgUlJSAKhcuXKB/dLS0qhTpw5ZWVlERETw0ksv0aRJkzz7ZmRkkJGRYXmfmpoKgNlsxmw2FzvWvOSMZ+9xywp3zw/cP0fl5/rcPUfl5/oclWNpfGYmwzCMonT08PCgTp06hIeHU9Aqy5YtK1YgWVlZ9O7dmwsXLrBx48Z8+23ZsoWDBw/SvHlzUlJSeO2111i/fj379u2jVq1aufpPnTqVadOm5WqPj48v1iE/ERERKX3p6en079+flJQUgoKCHLKNIhdFw4cP55NPPqFOnTo8+uijPPzww4Xu0bHFk08+yapVq9i4cWOexU1+zGYzjRs3JjY2lhkzZuRanteeotDQUM6ePWv3D9VsNpOQkEBUVBTe3t52HbsscPf8wP1zVH6uz91zVH6uz1E5pqamUrVqVYcWRUU+fPbOO+/wxhtv8OWXX7Jw4UImTJhAdHQ0Q4cOpVu3biU62XnEiBGsWLGC9evX21QQAXh7exMeHs6hQ4fyXO7r64uvr2+e6znqC+nIscsCd88P3D9H5ef63D1H5ef67J1jaXxeNl2S7+vrS2xsLAkJCezfv58mTZrw1FNPUbduXdLS0mzeuGEYjBgxgmXLlvH9999Tr149m8fIzMxkz549VK9e3eZ1RURERHIU++ozDw8PTCYThmGQmZlZrDGGDx9OfHw8//nPfwgMDOTUqVMAVKhQAX9/fwAGDhxIzZo1mTVrFgDTp0+nffv2NGjQgAsXLjB79myOHTvGsGHDipuKiIiIiG17ijIyMvjkk0+IioritttuY8+ePbz99tskJSUREBBg88bnzZtHSkoKnTt3pnr16pbXp59+aumTlJREcnKy5f358+d57LHHaNy4Mb169SI1NZXNmzdz++2327x9ERERkRxF3lP01FNPsWTJEkJDQxkyZAiffPIJVatWLdHGi3KOd2JiotX7OXPmMGfOnBJtV0RERORGRS6K3n33XWrXrs2tt97KunXrWLduXZ79vvzyS7sFJyIiIlJailwUDRw4UI/TEBEREbdV5KIoLi7OgWGIiIiIOJdNJ1qLiIiIuCsVRSIiIiKoKBIREREBVBSJiIiIACqKRERERAAVRSIiIiKAiiIRERERQEWRiIiICKCiSERERARQUSQiIiICqCgSERERAVQUiYiIiAAqikREREQAFUUi4qbOnTtHcHAwR48eLdXtXr16lbp167J9+/ZS3a470hxKaVNRJCJuaebMmfTp04e6desC2X/B9ujRgxo1auDr60toaCgjRowgNTXVpnFnzZpFmzZtCAwMJDg4mJiYGA4cOGBZ7uPjw9ixY3nuuefsmc5N6cY5vN65c+eoVasWJpOJCxcu2DSu5lDyo6JIRNxOeno6CxYsYOjQoZY2Dw8P+vTpw1dffcWvv/5KXFwca9as4YknnrBp7HXr1jF8+HB+/PFHEhISMJvNdOvWjUuXLln6DBgwgI0bN7Jv3z675XSzyWsOrzd06FCaN29erLE1h5IfFUUi4nZWrVqFr68v7du3t7RVqlSJJ598ktatW1OnTh26du3KU089xYYNG2wa+9tvv2Xw4ME0adKEFi1aEBcXR1JSEjt27LDaVseOHVmyZIndcrrZ5DWHOebNm8eFCxcYO3ZsscbWHEp+vJwdgIiIvW3atIlWrVoV2Of333/nyy+/pFOnTiXaVkpK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qE0DJ0cnRdH+nlZ8dOhtvnlvDXs27QfgwdH3Ej0siltquccJ8uIanLqnqChPKk5KSiI5OdnyvkOHDsTHx/Pee+/RokULPv/8c5YvX07Tpk2dkYKIlAH+5f3oNawr05aNB2DEW0NVELmYqjWrMGhaP2atyn68xoAXHlBBJKXOqXuKinLhW2JiYq62vn370rdvXwdEJCIiIjcrPftMREREBBVFIiIiIoCKIhERERFARZGIiIgIoKJIREREBFBRJCIiIgKoKBIREREBVBSJiIiIACqKRERERAAVRSIiIiKAiiIRERERQEWRiIiICKCiSERERARQUSQiIiICqCgSERERAVQUiYiIiAAqikREREQAFUUiIiIigIoiEREREUBFkYiIiAigokhEREQEUFEkIiIiAqgoEhEREQFUFImIiIgAKopEREREABVFIiIiIoCKIhERERFARZGIiIgIoKJIREREBFBRJCIiIgKoKBIREREBnFwUrV+/nnvvvZcaNWpgMplYvnx5gf0TExMxmUy5XqdOnSqdgEVERMRtObUounTpEi1atOCdd96xab0DBw6QnJxseQUHBzsoQhEREblZeDlz4z179qRnz542rxccHEzFihXtH5CIiIjctJxaFBVXy5YtycjIoGnTpkydOpWOHTvm2zcjI4OMjAzL+9TUVADMZjNms9muceWMZ+9xywp3zw/cP0fl5/rcPUfl5/oclWNpfGYmwzAMh2+lCEwmE8uWLSMmJibfPgcOHCAxMZHWrVuTkZHBBx98wMcff8zWrVuJiIjIc52pU6cybdq0XO3x8fGUK1fOXuGLiIiIA6Wnp9O/f39SUlIICgpyyDZcqijKS6dOnahduzYff/xxnsvz2lMUGhrK2bNn7f6hms1mEhISiIqKwtvb265jlwXunh+4f47Kz/W5e47Kz/U5KsfU1FSqVq3q0KLIJQ+fXa9t27Zs3Lgx3+W+vr74+vrmavf29nbYF9KRY5cF7p4fuH+Oys/1uXuOys/12TvH0vi8XP4+Rbt376Z69erODkNERERcnFP3FKWlpXHo0CHL+yNHjrB7924qV65M7dq1mTBhAidPnuSjjz4C4M0336RevXo0adKEK1eu8MEHH/D999/z3XffOSsFERERcRNOLYq2b99Oly5dLO9Hjx4NwKBBg4iLiyM5OZmkpCTL8qtXrzJmzBhOnjxJuXLlaN68OWvWrLEaQ0RERKQ4nFoUde7cmYLO846Li7N6P378eMaPH+/gqERERORm5PLnFImIiIjYg4oiEREREVQUiYiIiAAqikREREQAFUUiIiIigIoiEREREUBFkYiIiAigokhEREQEUFEkIiIiAqgoEhEREQFUFImIiIgAKopEREREABVFIiIiIoCKIhERERFARZGIiIgIoKJIREREBFBRJCIiIg5y7tw5goODOXr0aKlvu3379nzxxRc2raOiSERERBxi5syZ9OnTh7p161raTCZTrteSJUtsGnf9+vXce++91KhRA5PJxPLly3P1mTRpEs8//zxZWVlFHldFkYiIiNhdeno6CxYsYOjQobmWLVq0iOTkZMsrJibGprEvXbpEixYteOedd/Lt07NnTy5evMiqVauKPK6XTVGIiIiIFMGqVavw9fWlffv2uZZVrFiRkJCQYo/ds2dPevbsWWAfT09PevXqxZIlS4iOji7SuNpTJCIiIna3adMmWrVqleey4cOHU7VqVdq2bcvChQsxDMMhMbRt25YNGzYUub/2FImIiIjdHTt2jBo1auRqnz59OnfddRflypXju+++46mnniItLY1nnnnG7jHUqFGD48ePk5WVhYdH4fuBVBSJiIiI3V25cgU/P79c7f/4xz8sfw4PD+fSpUvMnj3bIUWRv78/WVlZZGRk4O/vX2h/HT4TERERu6tSpQrnz58vtF+7du04ceIEGRkZdo/hzz//pHz58kUqiEBFkYiIiDhAy5Yt2b9/f6H9du/eTaVKlfD19bV7DHv37iU8PLzI/XX4TEREROwuKiqKSZMmcf78eSpVqgTA119/zenTp2nfvj1+fn4kJCTw0ksvMXbsWJvGTktL49ChQ5b3R44cYffu3VSuXJnatWtb2jds2EC3bt2KPK72FImIiIjdNWvWjIiICD777DNLm7e3N++88w6RkZG0bNmS+fPn88YbbzBlyhRLn6NHj2IymUhMTMx37O3btxMeHm7ZCzR69GjCw8OZPHmypc/JkyfZvHkzjz76aJFj1p4iERERcYjJkyczbtw4HnvsMTw8POjRowc9evQocJ0jR45QsWJFWrRokW+fzp07F3oZ/1tvvcXgwYOpVatWkeNVUSQiIiIOER0dzcGDBzl58iShoaFFWmflypVMnDjRcsituIKDgxk9erRN66goEhEREYcZNWqUTf1nz55tl+2OGTPG5nV0TpGIiIiUSGZmJmsXb+CZDi/Qv/YTACx8IZ5TR884OTLbOLUoKspTbm+UmJhIREQEvr6+NGjQgLi4OIfHKSIiInnLvJbJ9Adf5+VH3uLATwe5lHoZgK/f/Y7Hm49h/4+/OjnConNqUVSUp9xe78iRI0RHR9OlSxd2797NqFGjGDZsGKtXr3ZwpCIiIpKXL+asYMtX2wHIyvrr5OesTIOMy1eZ0ucVzFfNzgrPJk49p6goT7m93rvvvku9evV4/fXXAWjcuDEbN25kzpw5dO/e3VFhioiISB6ysrJY9tbKfK8Ey8rM4sIfqWz88ie6/F/HUo7Odi51ovWWLVu4++67rdq6d+9e4ElcGRkZVrcOT01NBcBsNmM227dyzRnP3uOWFe6eH7h/jsrP9bl7jsrPtZxL/pOUPy/i7e9tafP297L6r6e3B7/89Ct3PNC2RNsqjc/MZBR2oX8pMZlMLFu2jJiYmHz73HbbbTz66KNMmDDB0rZy5Uqio6NJT0/P89kmU6dOZdq0abna4+PjKVeunF1iFxEREcdKT0+nf//+pKSkEBQU5JBtuNSeouKYMGGC1X0KUlNTCQ0NpVu3bnb/UM1mMwkJCURFReHt7V34Ci7G3fMD989R+bk+d89R+bkWwzB4uv0ETvyaTM4uFm9/L4YseICFQ7/AfPkaAJOXjqFVVPMSbSvnSI8juVRRFBISwunTp63aTp8+TVBQUL5PwPX19c3zIXPe3t4O+0I6cuyywN3zA/fPUfm5PnfPUfm5jgdG3svsR3NfMGW+fI0scybV64fQtkc4Hh4lu7arND4vl7pPUWRkJGvXrrVqS0hIIDIy0kkRiYiI3NyiBnai3/g+AHh6WZcVVWpU5qVvJpa4ICotTt1TVNhTbidMmMDJkyf56KOPAHjiiSd4++23GT9+PEOGDOH777/ns88+45tvvnFWCiIiIjc1k8nEsJcf5s4HI/lm/nck/fo7AMPnPspdsXfiX97PyREWnVOLou3bt9OlSxfL+5xzfwYNGkRcXBzJyckkJSVZlterV49vvvmGZ599lrlz51KrVi0++OADXY4vIiLiZI1a16dR6ycxm82sXLmSboM6u9whQqcWRYU95Tavu1V37tyZXbt2OTAqERERuRm5xkE+EREREQdTUSQiIiKCiiIRERERQEWRiIiICKCiSERERARQUSQiIiICqCgSERERAVQUiYiIiAAqikREREQAJ9/R2hly7qCdmppq97HNZjPp6emkpqa63K3Ni8Ld8wP3z1H5uT53z1H5uT5H5Zjz93ZBT8IoqZuuKLp48SIAoaGhTo5EREREbHXx4kUqVKjgkLFNhiNLrjIoKyuL33//ncDAQEwmk13HTk1NJTQ0lOPHjxMUFGTXscsCd88P3D9H5ef63D1H5ef6HJWjYRhcvHiRGjVq4OHhmLN/bro9RR4eHtSqVcuh2wgKCnLbLzu4f37g/jkqP9fn7jkqP9fniBwdtYcoh060FhEREUFFkYiIiAigosiufH19mTJlCr6+vs4OxSHcPT9w/xyVn+tz9xyVn+tz5RxvuhOtRURERPKiPUUiIiIiqCgSERERAVQUiYiIiAAqikREREQAFUVFtn79eu69915q1KiByWRi+fLlha6TmJhIREQEvr6+NGjQgLi4OIfHWRK25piYmIjJZMr1OnXqVOkEbKNZs2bRpk0bAgMDCQ4OJiYmhgMHDhS63tKlSwkLC8PPz49mzZqxcuXKUojWdsXJLy4uLtf8+fn5lVLEtpk3bx7Nmze33BAuMjKSVatWFbiOq8xdDltzdKX5y8vLL7+MyWRi1KhRBfZztXnMUZT8XG0Op06dmivesLCwAtdxpflTUVREly5dokWLFrzzzjtF6n/kyBGio6Pp0qULu3fvZtSoUQwbNozVq1c7ONLiszXHHAcOHCA5OdnyCg4OdlCEJbNu3TqGDx/Ojz/+SEJCAmazmW7dunHp0qV819m8eTOxsbEMHTqUXbt2ERMTQ0xMDHv37i3FyIumOPlB9l1nr5+/Y8eOlVLEtqlVqxYvv/wyO3bsYPv27dx111306dOHffv25dnfleYuh605guvM3422bdvG/Pnzad68eYH9XHEeoej5gevNYZMmTazi3bhxY759XW7+DLEZYCxbtqzAPuPHjzeaNGli1davXz+je/fuDozMfoqS4w8//GAAxvnz50slJns7c+aMARjr1q3Lt89DDz1kREdHW7W1a9fO+Pvf/+7o8EqsKPktWrTIqFChQukFZWeVKlUyPvjggzyXufLcXa+gHF11/i5evGg0bNjQSEhIMDp16mSMHDky376uOI+25OdqczhlyhSjRYsWRe7vavOnPUUOsmXLFu6++26rtu7d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3ZbX66+/TlxcHJmZmTblvWnTJp555hl69epFkyZN8PX15ezZs1Z9vL29bR73Ro0aNeLatWvs2rXL0nbo0CHOnz9fonFFpPhUFIlInjw9Pfnll1/Yv3+/1SGgHOXLl+fJJ59k3LhxfPvtt+zfv5/HHnuM9PR0hg4daulXt25dOnTowNChQ8nMzKR37975bnPAgAFUrVqVPn36sGHDBo4cOUJiYiLPPPMMJ06cyHOdBQsW8OCDD9K0aVOr19ChQzl79izffvutTXk3bNiQjz/+mF9++YWtW7cyYMAA/P39rfrUrVuXtWvXcurUqWIXMWFhYdx99908/vjj/PTTT+zatYvHH388z71XIlI6VBSJSL6CgoIICgrKd/nLL7/MAw88wCOPPEJERASHDh1i9erVuc6LGTBgAD///DP33XdfrgLjeuXKlWP9+vXUrl2b+++/n8aNGzN06FCuXLmSZxw7duzg559/5oEHHsi1rEKFCnTt2pUFCxbYkHF2kXX+/HkiIiJ45JFHLLccuN7rr79OQkICoaGhuW5TYIuPPvqIatWq8be//Y377ruPxx57jMDAQPz8/Io9pogUn8kwDMPZQYiICJw4cYLQ0FDWrFlD165dnR2OyE1HRZGIiJN8//33pKWl0axZM5KTkxk/fjwnT57k119/zXWStog4nq4+ExFxErPZzMSJE/ntt98IDAykQ4cOLF68WAWRiJNoT5GIiIgIOtFaREREBFBRJCIiIgKoKBIREREBVBSJiIiIACqKRERERAAVRSIiIiKAiiIRERERQEWRiIiICKCiSERERASA/we0slkUoVShJQAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.title(\"User Movie Preference\", size=15) \n",
    "plt.xlabel(\"Movie A rating\")\n",
    "plt.ylabel(\"Movie B rating\")\n",
    "plt.grid()\n",
    "\n",
    "# 绘制原始样本点，要求不同的影片喜好类别用不同的颜色标记\n",
    "# 提示: 用scatter散点图绘制，用它的参数c实现不同的类别用不同的颜色标记\n",
    "plt.scatter(X[:,0], X[:,1], c=y)\n",
    "\n",
    "# 绘制新数据点，用红色x标记，大小为8\n",
    "# 提示：用plt.plot()绘制，用它的参数marker实现不同的标记符号\n",
    "plt.plot(new_user[0][0], new_user[0][1], 'rx', markersize=8)\n",
    "\n",
    "#  新数据最近邻索引为第一个最近邻的索引\n",
    "dist, idx = knn.kneighbors(new_user)\n",
    "nearest = X[idx[0]] # 获取最近邻点的坐标，这是一个列表，第一个元素是x坐标，第二个元素是y坐标\n",
    "\n",
    "# 用红线标记新数据点与最近邻点的连接线\n",
    "# 提示：用plt.plot()绘制，用 r-- 实现红色虚线\n",
    "#plt.plot([X[0, 0], new_user[0]], [X[0, 1], new_user[1]], color='r', linestyle='--')\n",
    "plt.plot([nearest[0][0], new_user[0][0]], [nearest[0][1], new_user[0][1]], color='r', linestyle='--')\n",
    "# 为每个点添加坐标文本  \n",
    "for x, y in zip(X[:, 0], X[:, 1]):\n",
    "    plt.text(x, y+0.1, f'({x}, {y})') \n",
    "\n",
    "# 为新数据点添加坐标文本\n",
    "plt.text(new_user[0,0], new_user[0,1]+0.1, f'({new_user[0,0]}, {new_user[0,1]})')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e24a166d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "movie_env",
   "language": "python",
   "name": "movie_env"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
